package com.walterlife.javacore;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * @author zhuyuwei
 * @date 2017/7/19
 * @description:
 */
public class JUCTest {

/*    class BooleanLatch {
        private static class Sync extends AbstractQueuedSynchronizer {

            boolean isSignalled() {
                return getState() != 0;
            }

            protected int tryAcquireShared(int ignore) {
                return isSignalled() ? 1: -1;
            }

        }
    }*/

    public static void main(String[] args) {
        Map<Integer, Integer> intMap = new HashMap<>();
        intMap.put(1, 2);
        intMap.put(1, 4);
        System.out.println(intMap.toString());
//        countDownLatchTest();
        cyclicBarrierTest();

    }

    static class Writer extends Thread {
        private CyclicBarrier cyclicBarrier;
        public Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            System.out.println("线程" + Thread.currentThread().getName() + "正在写入数据...");
            try {
                Thread.sleep(5000);
                System.out.println("线程" + Thread.currentThread().getName() + "写入数据完毕，等待其他线程写入完毕");
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("所有线程写入完毕，继续处理其他任务...");
        }
    }

    public static void cyclicBarrierTest() {
        int N = 4;
        CyclicBarrier barrier = new CyclicBarrier(N);
        for (int i = 0; i < N; i++) {
            new Writer(barrier).start();
        }
    }

    public static  void countDownLatchTest() {
        CountDownLatch latch = new CountDownLatch(2);

        new Thread() {
            @Override
            public void run() {
                try {
                    System.out.println("子线程" + Thread.currentThread().getName() + "doing");
                    Thread.sleep(3000);
                    System.out.println("子线程" + Thread.currentThread().getName() + "done");
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                try {
                    System.out.println("子线程" + Thread.currentThread().getName() + "doing");
                    Thread.sleep(3000);
                    System.out.println("子线程" + Thread.currentThread().getName() + "done");
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
        try {
            System.out.println("等待2个子线程执行完毕...");
            latch.await();
            System.out.println("2个子线程已经执行完毕...");
            System.out.println("继续执行主线程...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
